#include "directdatachannel.h"
#include "websocketclient.h"
#include "unifiedgamerenderer.h"
#include <QDebug>
#include <QDateTime>

DirectDataChannel::DirectDataChannel(QObject *parent)
    : QObject(parent)
    , m_webSocketClient(nullptr)
    , m_renderer(nullptr)
    , m_running(false)
    , m_performanceTimer(new QTimer(this))
    , m_retryTimer(new QTimer(this))
    , m_lastMessageTime(0)
    , m_lastStatsUpdate(0)
{
    // 注册自定义类型
    qRegisterMetaType<GameStateInfo>("GameStateInfo");
    qRegisterMetaType<DirectDataChannel::PerformanceStats>("DirectDataChannel::PerformanceStats");

    // 设置支持的消息类型
    m_supportedMessageTypes << "game_state_update" << "game_end" << "game_started"
                           << "player_died" << "room_created" << "room_joined"
                           << "room_state_change" << "start_game_response";

    // 设置性能监控定时器
    m_performanceTimer->setInterval(STATS_UPDATE_INTERVAL);
    connect(m_performanceTimer, &QTimer::timeout, this, &DirectDataChannel::onPerformanceTimer);

    // 设置重试定时器
    m_retryTimer->setInterval(RETRY_INTERVAL);
    connect(m_retryTimer, &QTimer::timeout, this, &DirectDataChannel::processPendingMessages);

    qDebug() << "DirectDataChannel: 直接数据通道初始化完成";
}

DirectDataChannel::~DirectDataChannel()
{
    stop();
    qDebug() << "DirectDataChannel: 直接数据通道已销毁";
}

void DirectDataChannel::connectWebSocket(WebSocketClient *client)
{
    if (m_webSocketClient) {
        // 断开旧连接
        disconnect(m_webSocketClient, nullptr, this, nullptr);
    }
    
    m_webSocketClient = client;
    
    if (client) {
        // 连接WebSocket信号
        connect(client, &WebSocketClient::messageReceived,
                this, &DirectDataChannel::onWebSocketMessage, Qt::QueuedConnection);
        connect(client, &WebSocketClient::disconnected,
                this, [this]() {
                    emit connectionError("WebSocket连接断开");
                });
        
        qDebug() << "DirectDataChannel: WebSocket客户端已连接";
    } else {
        qDebug() << "DirectDataChannel: WebSocket客户端已断开";
    }
}

void DirectDataChannel::connectRenderer(UnifiedGameRenderer *renderer)
{
    if (m_renderer) {
        // 断开旧连接
        disconnect(m_renderer, nullptr, this, nullptr);
    }
    
    m_renderer = renderer;
    
    if (renderer) {
        // 连接渲染器信号
        connect(renderer, &UnifiedGameRenderer::gameEnded,
                this, &DirectDataChannel::onGameEnded, Qt::QueuedConnection);

        qDebug() << "DirectDataChannel: 统一渲染器已连接";

        // 渲染器就绪后，尝试冲刷未处理的消息
        if (!m_pendingMessages.isEmpty() && !m_retryTimer->isActive()) {
            qDebug() << "DirectDataChannel: 渲染器连接完成，准备冲刷缓存消息";
            m_retryTimer->start();
        }
    } else {
        qDebug() << "DirectDataChannel: 统一渲染器已断开";
    }
}

void DirectDataChannel::start()
{
    if (m_running) {
        return;
    }

    // 允许无渲染器先启动：用于尽早缓存早到的服务器状态
    m_running = true;

    if (!m_renderer) {
        qWarning() << "DirectDataChannel: 启动（未连接渲染器）— 将先缓存状态消息，待渲染器就绪后下发";
    } else {
        qDebug() << "DirectDataChannel: 启动成功 - 渲染器已连接，等待网络线程消息";
    }

    // 重置性能统计
    {
        QMutexLocker locker(&m_statsMutex);
        m_stats = PerformanceStats();
        m_lastStatsUpdate = QDateTime::currentMSecsSinceEpoch();
    }

    // 若已有缓存消息，启动重试定时器
    if (!m_pendingMessages.isEmpty() && !m_retryTimer->isActive()) {
        m_retryTimer->start();
    }

    // 启动性能监控
    m_performanceTimer->start();

    qDebug() << "DirectDataChannel: 直接数据通道已启动";
}

void DirectDataChannel::stop()
{
    if (!m_running) {
        return;
    }
    
    m_running = false;
    
    // 停止性能监控
    m_performanceTimer->stop();
    
    // 打印最终统计
    printPerformanceStats();
    
    qDebug() << "DirectDataChannel: 直接数据通道已停止";
}

void DirectDataChannel::onWebSocketMessage(const QJsonObject &message)
{
    // 降噪：只在关键事件或每60条打印一次摘要，避免UI线程IO阻塞
    static int logCount = 0;
    logCount++;

    if (logCount % 60 == 1) {
        qDebug() << "=== DirectDataChannel收到消息(每60条摘要) ===";
        qDebug() << "DirectDataChannel运行状态:" << m_running;
        qDebug() << "消息类型:" << message["type"].toString();
    }

    if (!m_running) {
        QString t = message["type"].toString();
        if (t == "game_state_update") {
            m_pendingMessages.append(message);
            if (!m_retryTimer->isActive()) m_retryTimer->start();
        }
        return;
    }

    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    QString messageType = message["type"].toString();

    if (logCount % 60 == 1) {
        qDebug() << "渲染器状态:" << (m_renderer != nullptr);
        if (m_renderer) qDebug() << "渲染器运行状态:" << m_renderer->isRunning();
    }

    if (messageType == "game_state_update") {
        if (logCount % 60 == 1) {
            QJsonObject data = message["data"].toObject();
            QJsonArray snakes = data["snakes"].toArray();
            QJsonArray foods = data["foods"].toArray();
            qDebug() << "game_state_update 摘要: snakes=" << snakes.size() << ", foods=" << foods.size();
        }
    }

    // 特殊处理error消息
    if (messageType == "error") {
        // 兼容顶层扁平和data包裹两种格式
        QJsonObject payload = message.contains("data") ? message["data"].toObject() : message;
        QString errorCode = payload["error_code"].toString();
        QString errorMessage = payload["error_message"].toString();
        qWarning() << "DirectDataChannel: 收到错误消息 -" << errorCode << ":" << errorMessage;

        // 业务错误：不视为连接错误，不停止数据通道，仅转发到UI
        emit gameError(QString("游戏错误 %1: %2").arg(errorCode, errorMessage));

        // 继续处理其他消息，不return
        qDebug() << "DirectDataChannel: 错误已转发，继续运行";
    }

    // 检查消息类型是否支持
    if (!m_supportedMessageTypes.contains(messageType)) {
        qDebug() << "DirectDataChannel: 忽略不支持的消息类型:" << messageType;
        return;
    }

    if (logCount % 60 == 1) {
        qDebug() << "DirectDataChannel: 处理消息类型:" << messageType;
    }

    if (messageType == "game_state_update") {
        if (!m_renderer || !m_renderer->isRunning()) {
            if (logCount % 60 == 1) {
                qDebug() << "渲染器未就绪，缓存消息";
            }
            m_pendingMessages.append(message);
            if (!m_retryTimer->isActive()) {
                m_retryTimer->start();
            }
            return;
        }

        // 直接发送到渲染器，跳过中间层
        m_renderer->updateGameState(message);

        if (logCount % 60 == 1) {
            qDebug() << "DirectDataChannel: updateGameState 已投递";
        }

        // 提取UI需要的信息并发送
        GameStateInfo info = extractGameStateInfo(message);
        emit gameStateChanged(info);

        // 更新性能统计
        updatePerformanceStats(currentTime);
        
    } else if (messageType == "game_end" || messageType == "player_died") {
        QString reason = message["reason"].toString();
        if (reason.isEmpty()) {
            reason = (messageType == "player_died") ? "玩家死亡" : "游戏结束";
        }

        // 增强死因信息显示
        QString detailedReason = reason;
        QJsonObject data = message.value("data").toObject();

        // 检查是否有详细的死因信息
        if (data.contains("collision_type")) {
            QString collisionType = data["collision_type"].toString();
            QJsonObject collisionPoint = data["collision_point"].toObject();
            int x = collisionPoint["x"].toInt();
            int y = collisionPoint["y"].toInt();

            if (collisionType == "WALL") {
                detailedReason = QString("撞墙死亡 - 位置:(%1,%2)").arg(x).arg(y);
            } else if (collisionType == "SELF") {
                detailedReason = QString("撞到自己 - 位置:(%1,%2)").arg(x).arg(y);
            } else if (collisionType == "SNAKE") {
                QString otherPlayer = data["other_player"].toString();
                detailedReason = QString("撞到其他蛇 - 位置:(%1,%2) 对手:%3").arg(x).arg(y).arg(otherPlayer);
            }
        }

        // 添加游戏统计信息
        if (data.contains("game_stats")) {
            QJsonObject stats = data["game_stats"].toObject();
            int finalScore = stats["final_score"].toInt();
            int gameTime = stats["game_time_seconds"].toInt();
            detailedReason += QString(" | 最终分数:%1 游戏时长:%2秒").arg(finalScore).arg(gameTime);
        }

        qDebug() << "DirectDataChannel: 游戏结束详情:" << detailedReason;
        emit gameEnded(detailedReason);
        
    } else if (messageType == "game_started") {
        qDebug() << "DirectDataChannel: 游戏已开始";

    } else if (messageType == "room_created" || messageType == "room_joined") {
        qDebug() << "DirectDataChannel: 房间事件:" << messageType;
        // 记录当前房间ID
        QJsonObject data = message.value("data").toObject();
        QString rid;
        if (messageType == "room_created") {
            rid = message.value("room_id").toString();
        } else {
            QJsonObject roomInfo = data.value("room_info").toObject();
            rid = roomInfo.value("room_id").toString();
        }
        if (!rid.isEmpty()) {
            m_currentRoomId = rid;
            m_consecutiveFinished = 0;
            qDebug() << "  当前房间ID记录为:" << m_currentRoomId;
        }

    } else if (messageType == "room_state_change") {
        // 尝试多个位置解析room_id和new_state
        QString rid = message.value("room_id").toString();
        if (rid.isEmpty()) {
            QJsonObject data = message["data"].toObject();
            rid = data.value("room_id").toString();
        }

        int newState = message.value("new_state").toInt();
        if (newState == 0) {
            QJsonObject data = message["data"].toObject();
            newState = data.value("new_state").toInt();
        }

        // 如果仍然没有room_id，使用当前记录的房间ID
        if (rid.isEmpty() && !m_currentRoomId.isEmpty()) {
            rid = m_currentRoomId;
            qDebug() << "DirectDataChannel: room_state_change 使用当前房间ID:" << rid;
        } else if (rid.isEmpty()) {
            qWarning() << "DirectDataChannel: room_state_change 缺少room_id，忽略该消息";
            return;
        }

        qDebug() << "DirectDataChannel: 房间状态变化，新状态:" << newState << " room_id:" << rid;

        // 仅处理当前房间ID的状态变化
        if (!m_currentRoomId.isEmpty() && !rid.isEmpty() && rid != m_currentRoomId) {
            qDebug() << "  忽略非当前房间的状态变化";
            return;
        }

        // 状态映射：0=WAITING, 1=PLAYING, 2=PAUSED, 3=FINISHED
        QString stateText;
        switch (newState) {
            case 0: stateText = "等待中"; break;
            case 1: stateText = "游戏中"; break;
            case 2: stateText = "暂停"; break;
            case 3: stateText = "已结束"; break;
            default: stateText = "未知状态"; break;
        }
        qDebug() << "  状态含义:" << stateText;

        // 结束态去抖：连续两次FINISHED才触发
        if (newState == 3) {
            m_consecutiveFinished++;
            if (m_consecutiveFinished >= 2) {
                emit gameEnded("游戏结束");
            } else {
                qDebug() << "  收到FINISHED(1/2)，等待下一次确认";
            }
        } else {
            m_consecutiveFinished = 0; // 其他状态重置
        }

    } else if (messageType == "start_game_response") {
        bool success = message["success"].toBool();
        qDebug() << "DirectDataChannel: start_game响应，成功:" << success;

        if (!success) {
            QString error = message["error"].toString();
            qDebug() << "  start_game失败:" << error;
        }
    }
}

void DirectDataChannel::onGameEnded(const QString &reason)
{
    qDebug() << "DirectDataChannel: 游戏结束，原因:" << reason;
    emit gameEnded(reason);
}

void DirectDataChannel::onPerformanceTimer()
{
    QMutexLocker locker(&m_statsMutex);
    
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    qint64 elapsed = currentTime - m_lastStatsUpdate;
    
    if (elapsed > 0) {
        // 计算吞吐量
        m_stats.throughput = double(m_stats.messagesProcessed) * 1000.0 / elapsed;
        
        // 重置计数器
        m_stats.messagesProcessed = 0;
        m_lastStatsUpdate = currentTime;
    }
    
    emit performanceStatsUpdated(m_stats);
}

void DirectDataChannel::processGameStateUpdate(const QJsonObject &message)
{
    // 这个方法已经在onWebSocketMessage中内联处理
    // 保留作为扩展点
}

GameStateInfo DirectDataChannel::extractGameStateInfo(const QJsonObject &gameState)
{
    GameStateInfo info;
    info.timestamp = QDateTime::currentMSecsSinceEpoch();
    
    QJsonObject data = gameState["data"].toObject();
    
    // 提取分数信息
    QJsonArray snakes = data["snakes"].toArray();
    if (!snakes.isEmpty()) {
        info.score = snakes[0].toObject()["score"].toInt();
    }
    
    // 提取游戏信息
    QJsonObject gameInfo = data["game_info"].toObject();
    info.alivePlayers = gameInfo["alive_players"].toInt();
    info.totalPlayers = gameInfo["total_players"].toInt();
    
    // 提取游戏状态
    int status = data["status"].toInt();
    switch (status) {
        case 0: info.gameStatus = "等待中"; break;
        case 1: info.gameStatus = "游戏中"; break;
        case 2: info.gameStatus = "暂停"; break;
        case 3: info.gameStatus = "结束"; break;
        default: info.gameStatus = "未知"; break;
    }
    
    // 计算延迟（如果有服务器时间戳）
    qint64 serverTimestamp = gameState["timestamp"].toVariant().toLongLong();
    if (serverTimestamp > 0) {
        info.avgLatency = double(info.timestamp - serverTimestamp);
    }
    
    return info;
}

void DirectDataChannel::updatePerformanceStats(qint64 messageTime)
{
    QMutexLocker locker(&m_statsMutex);
    
    m_stats.messagesProcessed++;
    
    // 计算延迟
    if (m_lastMessageTime > 0) {
        qint64 latency = messageTime - m_lastMessageTime;
        m_stats.totalLatency += latency;
        m_stats.averageLatency = m_stats.totalLatency / m_stats.messagesProcessed;
        
        if (m_stats.minLatency == 0 || latency < m_stats.minLatency) {
            m_stats.minLatency = latency;
        }
        if (latency > m_stats.maxLatency) {
            m_stats.maxLatency = latency;
        }
    }
    
    m_lastMessageTime = messageTime;
}

DirectDataChannel::PerformanceStats DirectDataChannel::getPerformanceStats() const
{
    QMutexLocker locker(&m_statsMutex);
    return m_stats;
}

void DirectDataChannel::printPerformanceStats() const
{
    QMutexLocker locker(&m_statsMutex);
    
    qDebug() << "=== DirectDataChannel 性能统计 ===";
    qDebug() << "已处理消息数:" << m_stats.messagesProcessed;
    qDebug() << "丢弃消息数:" << m_stats.messagesDropped;
    qDebug() << "平均延迟:" << m_stats.averageLatency << "ms";
    qDebug() << "最小延迟:" << m_stats.minLatency << "ms";
    qDebug() << "最大延迟:" << m_stats.maxLatency << "ms";
    qDebug() << "吞吐量:" << QString::number(m_stats.throughput, 'f', 2) << "消息/秒";
    
    if (m_stats.messagesProcessed > 0) {
        double dropRate = double(m_stats.messagesDropped) / (m_stats.messagesProcessed + m_stats.messagesDropped) * 100;
        qDebug() << "消息丢失率:" << QString::number(dropRate, 'f', 2) << "%";
    }
}

void DirectDataChannel::processPendingMessages()
{
    if (m_pendingMessages.isEmpty()) {
        m_retryTimer->stop();
        return;
    }

    // 检查渲染器是否现在就绪
    if (!m_renderer || !m_renderer->isRunning()) {
        qDebug() << "渲染器仍未就绪，继续等待。缓存消息数:" << m_pendingMessages.size();
        return;
    }

    qDebug() << "渲染器已就绪，处理" << m_pendingMessages.size() << "条缓存消息";

    // 处理所有缓存的消息
    while (!m_pendingMessages.isEmpty()) {
        QJsonObject message = m_pendingMessages.takeFirst();

        // 直接发送到渲染器
        m_renderer->updateGameState(message);

        // 提取UI需要的信息并发送
        GameStateInfo info = extractGameStateInfo(message);
        emit gameStateChanged(info);

        qDebug() << "处理缓存消息:" << message["type"].toString();
    }

    // 停止重试定时器
    m_retryTimer->stop();
    qDebug() << "所有缓存消息处理完成";
}
